/**
 * @fileOverview editor.Command 命令
 * @author goodzsq@gmail.com
 */

var BaseClass = gg.module('BaseObject');

module.exports = gg.createClass({
    attributes: {
    },
    methods: {
        _history: [], //历史命令记录
        _index: 0, //当前历史记录指针
        _lockHistory: false, //禁止修改历史记录
        _doCommand: function(commander) {
            this._lockHistory = true;
            if (typeof this[commander.cmd] === 'function') {
                this[commander.cmd].apply(this, commander.args);
            }
            this._lockHistory = false;
        },
        _pushHistory: function(cmd) {
            if (this._lockHistory) {
                return this._history;
            }
            if (typeof cmd === 'object') {
                this._history[this._index] = cmd;
                this._index++;
                this._history.length = this._index;
            }
            return this._history;
        },
        undo: function() {
            if (this._index > 0) {
                this._index--;
                var cmd = this._history[this._index];
                if (cmd) {
                    this._doCommand(cmd.undo);
                    return this._index;
                }
            }
        },
        redo: function() {
            var cmd = this._history[this._index];
            if (cmd) {
                this._doCommand(cmd.redo);
                this._index++;
                return this._index;
            }
        },
        selectObject: function(newId, oldId) {
            console.log('取消选择', oldId);
            var obj = gg.object(newId);
            if(obj){
                console.log('选中', newId);
                this._pushHistory({
                    redo:{
                        cmd:'selectObject',
                        args:[newId, oldId]
                    },
                    undo:{
                        cmd:'selectObject',
                        args:[oldId, newId]
                    }
                });
            }
        },
        /**
         * 创建对象
         * @param {Object} options
         * @param {Object} parent
         */
        createObject: function(options, parent) {
            if (!options.id) {
                options.id = gg.uuid();
            }
            console.log('history create', options.id);
            if (gg.object(options, parent)) {
                this._pushHistory({
                    redo: {
                        cmd: 'createObject',
                        args: [options, parent]
                    },
                    undo: {
                        cmd: 'destroyObject',
                        args: [options.id]
                    }
                });
            }
        },
        /**
         * 销毁对象
         * @param {String} id
         */
        destroyObject: function(id) {
            console.log('history destory', id);
            var obj = gg.object(id);
            if (obj) {
                var options = obj.toJSON();
                var parent = obj.parent;
                obj.destroy();
                this._pushHistory({
                    redo: {
                        cmd: 'destroyObject',
                        args: [id]
                    },
                    undo: {
                        cmd: 'createObject',
                        args: [options, parent]
                    }
                });
            }
        },
        /**
         * 修改对象的属性值
         * @param {String} id
         * @param {String} key
         * @param {Mixed} newValue
         */
        setObject: function(id, key, newValue) {
            var obj = gg.object(id);
            var oldValue = obj.get('key');
            if (obj && obj.set(key, newValue) !== false) {
                this._pushHistory({
                    redo: {
                        cmd: 'setObject',
                        args: [id, key, newValue]
                    },
                    undo: {
                        cmd: 'setObject',
                        args: [id, key, oldValue]
                    }
                });
            }
        }
    },
    events: {
    }
}, BaseClass, []);


/** @fileend */

//unittest
UnitTest.add('editor.Command模块测试',
        function() {
            var cmd = gg.module('editor.Command').create({});
            cmd.createObject({a: 1, b: 2, id:'a'});
            cmd.createObject({a: 3, b: 4, id:'b'});
            cmd.createObject({a: 3, b: 4, id:'c'});
            cmd.selectObject('a');
            cmd.selectObject('b', 'a');
            cmd.selectObject('c', 'b');
        }
);